﻿//#define _CRT_SECURE_NO_WARNINGS
//#include <stdio.h>
#include "study03.h"

// C/C++ 学习网站：https://legacy.cplusplus.com 注意旧版本（搜索）和新版本

/*
类(Class)是一种抽象概念，它是一组数据和操作数据的函数的集合。类可以包含数据成员（成员变量）和成员函数。
	类是一种模板，它定义了对象的属性和行为。类可以实例化为对象，对象是类的实例。
	对象可以访问类的成员变量和成员函数。类是一种方便代码重用的机制，
	它可以提高代码的可读性、可维护性和可扩展性。类能实现的功能不使用类也可以实现，

类可以包含以下元素：
	数据成员：类中的变量，用于存储对象的状态信息。
	成员函数：类中的函数，用于操作对象的数据。
	构造函数：类中的特殊函数，在创建对象时调用，用来初始化对象。
	析构函数：类中的特殊函数，在对象销毁时调用，用来释放对象占用的资源。
	友元函数：类中的函数，可以访问类的私有成员。
	静态成员：类中的变量，属于整个类，不属于对象，可以被所有对象共享。
	嵌套类：类中定义的类，可以访问类的私有成员。


类的定义：
	class 类名 {
	public: // 公有成员函数，外部可以访问
		// 成员变量
		// 成员函数
	};

实例化对象：
	类名 对象名;

调用成员函数：
	对象名.成员函数名();

访问成员变量：
	对象名.成员变量名;

注意：
	1. 类名、对象名、成员函数名、成员变量名都必须遵循标识符的命名规范。
	2. 类名必须首字母大写，成员函数名和成员变量名必须首字母小写。
	3. 类中的成员函数可以访问类中的成员变量，但不能访问类的其他成员函数。
	4. 类中的成员变量可以直接访问，不需要通过函数来访问。
	5. 类中的成员函数可以有参数，参数可以是基本数据类型、自定义类型、指针、引用。
	6. 类中的成员函数可以有返回值，返回值可以是基本数据类型、自定义类型、指针、引用。
	7. 类中的成员函数可以有重载，但不能有同名的重载函数。
	8. 类中的成员函数可以有默认参数值。
	9. 类中的成员函数可以有 const 修饰符。
	10. 类中的成员函数可以有 static 修饰符。
	11. 类中的成员函数可以有 inline 修饰符。
	12. 类中的成员函数可以有 virtual 修饰符。
	13. 类中的成员函数可以有 override 修饰符。
	14. 类中的成员函数可以有 final 修饰符。
	15. 类中的成员函数可以有 constexpr 修饰符。
	16. 类中的成员函数可以有 noexcept 修饰符。

类与结构体的区别：
	类是一种抽象概念，它是一组数据和操作数据的函数的集合。类可以包含数据成员（成员变量）和成员函数。
	结构是一种数据类型，它是一组数据成员的集合。结构不能包含成员函数。
	类可以实例化为对象，对象是类的实例。结构不能实例化为对象。
	类可以包含构造函数、析构函数、友元函数、静态成员、嵌套类。结构不能包含这些元素。
	类可以多继承，结构只能单继承。
	类默认成员都是私有成员，结构默认成员都是公有成员。

类的继承：
	类可以从其他类继承，继承的类称为基类（base class），被继承的类称为派生类（derived class）。
	派生类可以访问基类的所有成员，包括数据成员和成员函数，包括私有成员。
	派生类可以重写基类中的成员函数，但不能继承基类中的私有成员。
	派生类可以添加新的成员函数。也可以重新定义基类中的成员变量。还可以声明新的基类。
	类继承的语法：
		class 派生类名 : public 基类名, [public] 基类名2, ... { };    [] 表示可选（可以省略）
			public: // 公有成员函数，可以实现以下工作：
				// 重写基类中的成员函数
				// 添加新的成员函数
				// 重新定义基类中的成员变量
				// 声明新的基类

类的多态性：
	多态性是指一个对象可以具有多个形态，即可以具有不同的行为。
	在 C++ 中，多态性是通过虚函数和虚基类实现的。
	虚函数是指派生类中可以重新定义的成员函数，它提供了一种动态绑定的机制。
	虚基类是指派生类中可以作为基类的类，它提供了一种纯虚函数的机制。

类的友元：
	类可以声明友元函数，友元函数可以访问类的私有成员。
	友元函数的声明语法：
		class 类名 {
		public:
			// 友元函数声明
			friend void 友元函数名(类名& obj);
		};
	友元函数的定义语法：
		void 友元函数名(类名& obj) {
			// 访问私有成员
		}
*/

int main()
{
	// 指针和引用
	test_pointer_and_reference();

	// 初识类
	{
		print_start("初识类部分");
		Player player1; // 实例化对象
		std::cout << "sizeof string is " << sizeof(std::string) << std::endl;
		std::cout << "sizeof Entity is " << sizeof(Entity) << std::endl;
		std::cout << "sizeof Player is " << sizeof(Player) << std::endl;
		player1.name = "Player1"; // 访问公有成员变量，赋值
		player1.sex = "Male"; // 访问公有成员变量，赋值
		player1.x = 10.2f;
		player1.y = 20.3f;
		player1.speed = 4.5f;
		//player1.say_something("player1"); // err 不能访问父类私有成员

		std::cout << "Player1's name is " << player1.name << std::endl;
		std::cout << "Player1's sex is " << player1.sex << std::endl;
		std::cout << "Player1's x is " << player1.x << std::endl;
		std::cout << "Player1's y is " << player1.y << std::endl;
		std::cout << "Player1's speed is " << player1.speed << std::endl;
		std::cout << "Player1;s float_move(1.2, 1.2) = " << player1.float_move(1.2f, 1.2f)
			<< std::endl;

		print_end("初识类部分");
	}

	// 测试 C++ 结构体
	{
		print_start("测试 C++ 结构体部分");
		Point point1; // 实例化对象
		point1.x = 10;
		point1.y = 20;
		point1.speed = 5;
		std::cout << "sizeof Point is " << sizeof(Point) << std::endl;
		std::cout << "point1's x is " << point1.x << std::endl;
		std::cout << "point1's y is " << point1.y << std::endl;
		std::cout << "point1's speed is " << point1.speed << std::endl; // 有点奇怪的写法
		std::cout << "point1.move(point1, 1, 1) = "
			<< point1.move(point1, 1, 1) << std::endl; // 调用成员函数
		std::cout << "new point1's x is " << point1.x << std::endl;
		std::cout << "new point1's y is " << point1.y << std::endl;

		print_end("测试 C++ 结构体部分");
	}

	// 简单设计一个日志类 Log 用于记录日志信息
	{
		print_start("简单设计一个日志类 Log 用于记录日志信息");
		Log log1;
		log1.set_level(log1.警告); // 设置日志级别
		log1.print_log("This is a test log."); // 写入日志信息
		print_end("简单设计一个日志类 Log 用于记录日志信息");
	}

	// C++ 中简单了解结构体和类中的静态 static 关键字
	test_static();

	// C++ 中简单了解类中的基本函数
	test_base_function();

	//system("pause");   // 等待用户输入(按任意键继续)
	return 0;
}